package com.media.selector.media.preview

import android.app.Activity
import android.content.Intent
import android.os.Bundle
import android.view.View
import androidx.annotation.NonNull
import androidx.annotation.Nullable
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.databinding.DataBindingUtil
import androidx.databinding.ObservableInt
import androidx.fragment.app.FragmentActivity
import androidx.viewpager2.widget.ViewPager2
import com.media.selector.BR
import com.media.selector.R
import com.media.selector.databinding.ActivityMediaPreviewBinding
import com.media.selector.media.helper.createViewPagerAdapter
import com.media.selector.media.helper.setToolbar
import com.media.selector.media.model.SelectedCollection
import com.media.selector.media.model.SelectionSpec
import com.media.selector.media.model.entity.MediaEntity

/**
 * date        ：2020/5/13
 * author      ：蒙景博
 * description ：
 */
class MediaPreviewActivity: AppCompatActivity(), View.OnClickListener {

    companion object {

        private const val EXTRA_CLICK_TYPE = "extra_click_type"
        private const val EXTRA_CLICK_POSITION = "extra_click_position"
        private const val EXTRA_ALL_BUNDLE = "extra_all_bundle"
        private const val EXTRA_SELECTED_BUNDLE = "extra_selected_bundle"

        const val EXTRA_RESULT_BUNDLE = "extra_result_bundle"
        const val EXTRA_RESULT_APPLY = "extra_result_apply"

        fun start(@NonNull activity: FragmentActivity, requestCode: Int, clickType: Boolean, position: Int, @Nullable all: Bundle?, @Nullable selected: Bundle?) {
            activity.startActivityForResult(Intent(activity, MediaPreviewActivity::class.java).apply {
                putExtra(EXTRA_CLICK_TYPE, clickType)
                putExtra(EXTRA_CLICK_POSITION, position)
                putExtra(EXTRA_ALL_BUNDLE, all)
                putExtra(EXTRA_SELECTED_BUNDLE, selected)
            }, requestCode)
        }
    }

    private lateinit var mBinding: ActivityMediaPreviewBinding
    private val mCurrentPosition = ObservableInt(0)
    private val mFragments = mutableListOf<MediaPreviewFragment>()
    private val mSelectedCollection by lazy { SelectedCollection(this) }
    private val mOnPageChangeCallback by lazy { OnPageChangeCallback() }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        mBinding = DataBindingUtil.setContentView(this, R.layout.activity_media_preview)
        mBinding.lifecycleOwner = this
        mBinding.setVariable(BR.data, this)
        // 设置 Toolbar
        setToolbar(mBinding.mediaPreviewToolbar) { onBackPressed() }
        // 处理传入的数据及Bundle
        setViewData(savedInstanceState)
    }

    private fun setViewData(savedInstanceState: Bundle?) {
        val mClickType = intent.getBooleanExtra(EXTRA_CLICK_TYPE, false)
        val mClickPosition = intent.getIntExtra(EXTRA_CLICK_POSITION, 0)
        val mAllMediaBundle = intent.getBundleExtra(EXTRA_ALL_BUNDLE)
        val mSelectedMediaBundle = intent.getBundleExtra(EXTRA_SELECTED_BUNDLE)
        val mAllMedias = mAllMediaBundle?.getParcelableArrayList<MediaEntity>(SelectedCollection.STATE_ALL_DATA)
        val mSelectedMedias = mSelectedMediaBundle?.getParcelableArrayList<MediaEntity>(SelectedCollection.STATE_SELECTION)
        // 将数据存储到 SelectedCollection
        mSelectedCollection.onCreate(savedInstanceState ?: mSelectedMediaBundle)
        // 设置确定按钮
        setConfirmText(mSelectedMedias?.size ?: 0)
        // 设置View内容
        if (mFragments.isNotEmpty()) mFragments.clear()
        mFragments.addAll((if (mClickType) mSelectedMedias else mAllMedias)?.map { MediaPreviewFragment.with(it) } ?: listOf())
        mBinding.mediaPreviewContainer.adapter = createViewPagerAdapter(mFragments)
        mBinding.mediaPreviewContainer.setCurrentItem(mClickPosition, false)
        mBinding.mediaPreviewContainer.registerOnPageChangeCallback(mOnPageChangeCallback)
        mCurrentPosition.set(mClickPosition)
        // 设置默认选中状态
        setMediaSelectState(mClickPosition)
        // 切换ViewPager时间，修选中状态
        mOnPageChangeCallback.setOnPageSelectedListener {
            mCurrentPosition.set(it)
            setMediaSelectState(it)
        }
    }

    private fun setMediaSelectState(position: Int) {
        val mChecked = mFragments[position].getMedia()?.let { data -> mSelectedCollection.isSelected(data) } ?: false
        val mCheckDrawable = ContextCompat.getDrawable(this, if (mChecked) R.drawable.svg_media_check_sel else R.drawable.svg_media_check_nor)
        mBinding.mediaSelectActionCheck.setImageDrawable(mCheckDrawable)
    }

    private fun setConfirmText(selectedSize: Int) {
        mBinding.mediaPreviewConfirm.isClickable = selectedSize > 0
        val mConfirmTxt = getString(R.string.media_confirm_action)
        val mMaxSelectable = SelectionSpec.with().maxSelectable
        mBinding.mediaPreviewConfirm.text = if (selectedSize > 0) String.format("$mConfirmTxt(%s/%s)", selectedSize, mMaxSelectable) else mConfirmTxt
    }

    override fun onDestroy() {
        super.onDestroy()
        mBinding.mediaPreviewContainer.unregisterOnPageChangeCallback(mOnPageChangeCallback)
    }

    override fun onBackPressed() {
        sendBackResult(false)
        super.onBackPressed()
    }

    override fun onClick(v: View?) {
        if (v?.id == R.id.media_preview_confirm) {
            sendBackResult(true)
        } else if(v?.id == R.id.media_select_action) {
            handleSelectState()
        }
    }

    private fun sendBackResult(apply: Boolean) {
        setResult(Activity.RESULT_OK, Intent().apply {
            putExtra(EXTRA_RESULT_BUNDLE, mSelectedCollection.getSelectedDataBundle())
            putExtra(EXTRA_RESULT_APPLY, apply)
        })
        finish()
    }

    private fun handleSelectState() {
        val mMedia = mFragments[mCurrentPosition.get()].getMedia()
        mMedia?.let {
            val mSelected = mSelectedCollection.isSelected(it)
            if (!mSelected && mSelectedCollection.checkSelectedMedia(it)) {
                mSelectedCollection.addMedia(it)
                mBinding.mediaSelectActionCheck.setImageDrawable(ContextCompat.getDrawable(this, R.drawable.svg_media_check_sel))
            } else {
                mSelectedCollection.removeMedia(it)
                mBinding.mediaSelectActionCheck.setImageDrawable(ContextCompat.getDrawable(this, R.drawable.svg_media_check_nor))
            }
            setConfirmText(mSelectedCollection.getSelectedMediaSize())
        }
    }

    private inner class OnPageChangeCallback: ViewPager2.OnPageChangeCallback() {

        private var mOnPageSelectedListener: ((Int) -> Unit)? = null

        fun setOnPageSelectedListener(listener: (position: Int) -> Unit) {
            this.mOnPageSelectedListener = listener
        }

        override fun onPageSelected(position: Int) {
            mOnPageSelectedListener?.invoke(position)
        }
    }
}